module data_drive (
    input			wire						vga_clk         ,      // VGA时钟输入
    input			wire						rst_n           ,        // 复位信号，低电平有效
    input			wire		[ 11:0 ]		addr_h          ,       // 水平地址输入
    input			wire		[ 11:0 ]		addr_v          ,       // 垂直地址输入
    input			wire		[ 2:0 ]		    key             ,          // 三个按键输入

    input           wire        [18:0]          data_o          ,         // 测得的距离数据输入！！！！！！！！！！！
 
    // output			reg		    [ 15:0 ]		rgb_data      // 输出的RGB数据
    output			reg		    [ 23:0 ]		rgb_data
 
);
 
// 定义一些颜色的16位表示
// localparam	red    = 16'd63488;
// localparam	orange = 16'd64384;
// localparam	yellow = 16'd65472;
// localparam	green  = 16'd1024;
// localparam	blue   = 16'd31;
// localparam	indigo = 16'd18448;
// localparam	purple = 16'd32784;
// localparam	white  = 16'd65503;
// localparam	black  = 16'd0;

    localparam      orange      =       24'd16750899        ;   // 11111100_11111111_00001000
    localparam      yellow      =       24'd16776960        ;   // 11111111_11111111_10000000
    localparam      green       =       24'd65280           ;  // 00111111_11111111_00000000
    localparam      blue        =       24'd255             ;   // 00000001_11111111_00000000
    localparam      indigo      =       24'd10027161        ;    // 01111100_10000000_00000000
    localparam      purple      =       24'd16738047        ;   // 00001111_11111111_00000000
    localparam      white       =       24'd16777215        ;   // 11111111_11111111_11111111
    localparam      black       =       24'd0               ;   // 00000000_00000000_00000000
    localparam      red         =       24'd16711936        ;   // 11111111_11111111_11110000


// 当前状态和下一个状态的寄存器
reg			[ 2:0 ]			states_current			; // 当前状态
reg			[ 2:0 ]			states_next			    ; // 下个状态

// 定义显示状态的参数
localparam	        states_1 = 1        ; // 彩条
localparam	        states_2 = 2        ; // 字符
localparam	        states_3 = 3        ; // 图片



//显示的名字
// 存储显示字符的每一行数据
// reg [ 383:0 ] char_line[ 64:0 ];
// 
//李菊芳-632109160602  -16
//16行，每行152个bit
// reg [ 152:0 ] char_line[ 15:0 ];
// 
//李菊芳-632109160602 ——32
//32*3+16*13 = 304 304/8 = 38
reg         [ 303:0 ]           char_line[ 31:0 ];





// 图片的尺寸参数
//原始图片
// parameter	        height = 78     ; // 图片高度
// parameter	        width  = 128    ; // 图片宽度
//ikun2图片   
// parameter	        height = 52     ; // 图片高度
// parameter	        width  = 52     ; // 图片宽度
//warning警示图片的
parameter	            height = 400    ; // 图片高度
parameter	            width  = 400    ; // 图片宽度












// ROM的地址寄存器和数据输出
//ikun图片
// reg			[ 13:0 ]		rom_address				; // ROM地址
// wire		    [ 15:0 ]		rom_data				; // 图片数据
//warning警示图片的
reg			    [ 17:0 ]		rom_address				; // ROM地址
wire		    [ 23:0 ]		rom_data				; // 显示彩色图片数据






// 状态机的标志位
wire							flag_enable_out1			; // 文字有效区域标志
wire							flag_enable_out2			; // 图片有效区域标志
wire							flag_clear_rom_address		; // ROM地址清零标志
wire							flag_begin_h			    ; // 图片显示行开始标志
wire							flag_begin_v			    ; // 图片显示列开始标志



// 状态转移逻辑
always @( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        states_current <= states_1;// 复位时设置初始状态为彩条
    end
    else begin
        states_current <= states_next;// 否则转移到下一个状态
    end
end



/*
// 状态判断逻辑，根据按键输入更新下一个状态
always @( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        states_next <= states_1;
    end
    else if ( key[ 0 ] ) begin
        states_next <= states_1;
    end
        else if ( key[ 1 ] ) begin
        states_next <= states_2;
        end
        else if ( key[ 2 ] ) begin
        states_next <= states_3;
        end
    else begin
        states_next <= states_next;
    end
end
// */

// /*
// 状态判断逻辑，根据distance输入更新下一个状态
always @( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        states_next <= states_1;
    end
    else if(data_o/1000 <= 20) begin// 距离小于或等于20cm时
        states_next <= states_3;// 显示 警告warning 图片
    end
    else if(data_o/1000 > 20 && data_o/1000 <=60) begin//20-40cm
        states_next <= states_2;// 周围存在障碍物
        end
    else if ( data_o/1000 >=60) begin//大于60cm
        states_next <= states_2;//显示 “安全” 字样
        end
    else begin
        states_next <= states_next;
    end
end
// */




// 状态输出逻辑，根据不同的状态输出不同的RGB数据
always @( * ) begin
    case ( states_current )
        //彩条
        states_1 : begin
            // if ( flag_enable_out2 ) begin
                // rgb_data = rom_data;
            // end
            // else begin
                // rgb_data = black;
            // end
            //             
            if ( addr_h == 0 ) begin
                rgb_data = black;
            end
            else if ( addr_h >0 && addr_h <81 ) begin
                rgb_data = red;
            end
            else if ( addr_h >80 && addr_h <161 ) begin
                rgb_data = orange;
            end
            else if ( addr_h >160 && addr_h <241 ) begin
                rgb_data = yellow;
            end
            else if ( addr_h >240 && addr_h <321 ) begin
                rgb_data = green;
            end
            else if ( addr_h >320 && addr_h <401 ) begin
                rgb_data = blue;
            end
            else if ( addr_h >400 && addr_h <481 ) begin
                rgb_data = indigo;
            end
            else if ( addr_h >480 && addr_h <561 ) begin
                rgb_data = purple;
            end
            else if ( addr_h >560 && addr_h <641 ) begin
                rgb_data = white;
            end
            else begin
                rgb_data = black;
            end
             
        end
        //字符
        states_2 : begin
            if ( flag_enable_out1 ) begin
                //480*640
                // rgb_data = char_line[ addr_v-208 ][ 532 - addr_h ]? white:black;
                rgb_data = char_line[ addr_v-224 ][ 472 - addr_h ]? white:black;
            end
            else begin
                rgb_data = black;
            end
        end
        //图片
        states_3 : begin
            if ( flag_enable_out2 ) begin
                rgb_data = rom_data;
            end
            else begin
                rgb_data = black;
            end
            // 
        end
        default: begin
            case ( addr_h )
                0 : rgb_data      = black;
                1 : rgb_data      = red;
                81 : rgb_data     = orange;
                161: rgb_data     = yellow;
                241: rgb_data     = green;
                321: rgb_data     = blue;
                401: rgb_data     = indigo;
                481: rgb_data     = purple;
                561: rgb_data     = white;
                default: rgb_data = rgb_data;
            endcase
        end
    endcase
end
 
//醉意千层梦的 居中显示参数
// 根据当前状态和地址范围设置标志位
// assign flag_enable_out1 = states_current == states_2 && addr_h > 148 && addr_h < 533 && addr_v > 208  && addr_v < 273 ;
 
 
//李骏飞的居中显示参数
//32*3+16*13 = 304 304/8 = 38
// 根据当前状态和地址范围设置标志位
parameter ljf_width = 304;  // 字符数据的宽度
parameter ljf_height = 32;  // 字符数据的高度
//文字有效标志
assign flag_enable_out1 = states_current == states_2 && 
                           addr_h >= (640 - ljf_width) / 2 && 
                           addr_h <  ((640 - ljf_width) / 2) + ljf_width && 
                           addr_v >= (480 - ljf_height) / 2 && 
                           addr_v <  ((480 - ljf_height) / 2) + ljf_height;
 

//图片有效标志 width=640 height=480
assign flag_begin_h     = addr_h > ( ( 640 - width ) / 2 ) && addr_h < ( ( 640 - width ) / 2 ) + width + 1;
assign flag_begin_v     = addr_v > ( ( 480 - height )/2 ) && addr_v <( ( 480 - height )/2 ) + height + 1; 
assign flag_enable_out2 = states_current == states_3 && flag_begin_h && flag_begin_v;




//ROM地址计数器
always @( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        rom_address <= 0;// 复位时清零ROM地址
    end
    else if ( flag_clear_rom_address ) begin //计数满清零
        rom_address <= 0;
    end
    else if ( flag_enable_out2 ) begin  //在有效区域内+1
        rom_address <= rom_address + 1;
    end
    else begin  //无效区域保持
        rom_address <= rom_address;
    end
end
assign flag_clear_rom_address = rom_address == height * width - 1 || states_current != states_3;


/*
// 初始化显示文字的逻辑
always@( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        //李菊芳-632109160602
        //16*3+13*8=152 152/8=19个字节
        char_line[0]=152'h01000440082000000000000000000000000000;
        char_line[1]=152'h01000440082000000000000000000000000000;
        char_line[2]=152'h7FFCFFFEFFFE00000000000000000000000000;
        char_line[3]=152'h03800440082000183C3C08183808181818183C;
        char_line[4]=152'h054010000A2000244242382444382424242442;
        char_line[5]=152'h09201FFC010000404242084242084042404242;
        char_line[6]=152'h31182204FFFE00400242084242084042404242;
        char_line[7]=152'hC10652440400005C0402084242085C425C4202;
        char_line[8]=152'h0FE08A8404007E621804084246086242624204;
        char_line[9]=152'h0040020407F00042040808423A084242424208;
        char_line[10]= 152'h00807FF4041000420210084202084242424210;
        char_line[11]= 152'hFFFE0704081000424220084202084242424220;
        char_line[12]= 152'h01000A84081000224242082424082224222442;
        char_line[13]= 152'h010012441010001C3C7E3E18183E1C181C187E;
        char_line[14]= 152'h0500621420A000000000000000000000000000;
        char_line[15]= 152'h02000208404000000000000000000000000000;
// 
    end
end
// */





// /*
// 初始化显示文字的逻辑
always@( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        //李菊芳-632109160602 ——32
        //32*3+16*13 = 304 304/8 = 38
        char_line[0] =  304'h0000000000000000000000000000000000000000000000000000000000000000000000000000;
        char_line[1] =  304'h0000000000000000000000000000000000000000000000000000000000000000000000000000;
        char_line[2] =  304'h0003800000101000002008000000000000000000000000000000000000000000000000000000;
        char_line[3] =  304'h0003C000001C1C0000380E000000000000000000000000000000000000000000000000000000;
        char_line[4] =  304'h000380100018180000300C000000000000000000000000000000000000000000000000000000;
        char_line[5] =  304'h000380380018181800300C300000000000000000000000000000000000000000000000000000;
        char_line[6] =  304'h3FFFFFFC3FFFFFFC1FFFFFF8000001E007C007E0008003C007C0008001E003C001E003C007E0;
        char_line[7] =  304'h180FE0000098180000300C000000061818600838018006201820018006180620061806200838;
        char_line[8] =  304'h001FF00000D8180000330C0000000C18303010181F800C3030101F800C180C300C180C301018;
        char_line[9] =  304'h003FB80000F8180000318C00000008183018200C01801818301801800818181808181818200C;
        char_line[10] = 304'h 007B9C00019000200030C800000018003018200C01801818600801801800181818001818200C;
        char_line[11] = 304'h 00F39E0001FFFFF000006000000010003018300C01801808600C01801000180810001808300C;
        char_line[12] = 304'h 01E38F800300003000004030000010000018300C0180300C600C01801000300C1000300C300C;
        char_line[13] = 304'h 03C387F0020300301FFFFFF8000030000018000C0180300C600C01803000300C3000300C000C;
        char_line[14] = 304'h 07838DFE0483083000060000000033E0003000180180300C600C018033E0300C33E0300C0018;
        char_line[15] = 304'h 1FFFFEF808431C300006000000003630006000180180300C600C01803630300C3630300C0018;
        char_line[16] = 304'h 38401F3010631830000C00007FFE381803C000300180300C701C01803818300C3818300C0030;
        char_line[17] = 304'h 60003C0020633030000C008000003808007000600180300C302C01803808300C3808300C0060;
        char_line[18] = 304'h 0001F00000232330000FFFC00000300C001800C00180300C186C0180300C300C300C300C00C0;
        char_line[19] = 304'h 0001E0000FFFFFB0000C00C00000300C000801800180300C0F8C0180300C300C300C300C0180;
        char_line[20] = 304'h 0001E010000F0030000C01800000300C000C03000180300C000C0180300C300C300C300C0300;
        char_line[21] = 304'h 0001C038000B8030001801800000300C000C02000180300C00180180300C300C300C300C0200;
        char_line[22] = 304'h 7FFFFFFC001B6030001801800000300C300C04040180180800180180300C1808300C18080404;
        char_line[23] = 304'h 3801C00000333830003001800000180C300C08040180181800100180180C1818180C18180804;
        char_line[24] = 304'h 0001C00000631C20003001800000180830081004018018183030018018081818180818181004;
        char_line[25] = 304'h 0001C00000C30C200060030000000C183018200C01800C30306001800C180C300C180C30200C;
        char_line[26] = 304'h 0001C0000183046000C0030000000E3018303FF803C0062030C003C00E3006200E3006203FF8;
        char_line[27] = 304'h 0001C000020300600180C300000003E007C03FF81FF803C00F801FF803E003C003E003C03FF8;
        char_line[28] = 304'h 003FC0000C030FE002003E000000000000000000000000000000000000000000000000000000;
        char_line[29] = 304'h 0007C000300303C00C001E000000000000000000000000000000000000000000000000000000;
        char_line[30] = 304'h 0003800000020080300008000000000000000000000000000000000000000000000000000000;
        char_line[31] = 304'h 0000000000000000000000000000000000000000000000000000000000000000000000000000;  
    end
end
// */



//显示图片！！！！！！！！！！！！！！！！！！！

/*
//原神
// ROM实例化，根据地址输出数据
rom	rom_inst (
.address ( rom_address ),
.clock ( vga_clk ),
.q ( rom_data )
);
// */

/*
//ikun
// ROM实例化，根据地址输出数据
ikun_rom	ikun_rom_inst (
.address ( rom_address ),
.clock ( vga_clk ),
.q ( rom_data )
);
// */


// /*
//warning 距离小于给定值
// ROM实例化，根据地址输出数据
warning_rom	warning_rom_inst (
.address ( rom_address ),
.clock ( vga_clk ),
.q ( rom_data )
);
// */


endmodule // data_drive